# -*- coding: utf-8 -*-

import struct
import pickle
import forward_client


_g_forward_login_instance = None


# @Singleton
class ForwardLogin(object):

    # __metaclass__ = Singleton

    def __init__(self):
        super(ForwardLogin, self).__init__()
        self._try_broadcast_failed = False
        self._login_data_tmp = None
        forward_client.Get().bind_connect_success(self._connected_callback)

    def broadcast_login(self, self_eid, login_data):
        forward_client.Get().set_self_eid(self_eid)
        if forward_client.Get().is_connected():
            payload = ForwardLogin._make_login_payload(login_data)
            forward_client.Get().send_msg(forward_client.ForwardClient.CMD_LOGIN,
                                          self_eid,
                                          [forward_client.ForwardClient.BROADCAST_EID],
                                          payload)
        else:
            self._try_broadcast_failed = True
            self._login_data_tmp = login_data

    def broadcast_logout(self):
        forward_client.Get().send_msg(forward_client.ForwardClient.CMD_LOGOUT,
                                   forward_client.Get().get_self_eid(),
                                   [forward_client.ForwardClient.BROADCAST_EID])

    def bind_recv_login(self, func):
        # 接收到其他登录报文时的处理  func(src_eid, 你是否需要把所有数据同步给该src_eid, src_eid的登录数据)
        def real_func(src_eid, dst_eid_list, payload):
            need_sync = (struct.unpack('i', payload[:4])[0] != 0)
            login_data = pickle.loads(payload[4:])
            func(src_eid, need_sync, login_data)
        forward_client.Get().bind_cmd_recv(forward_client.ForwardClient.CMD_LOGIN, real_func)

    def _connected_callback(self):
        if self._try_broadcast_failed:      # 还没连上之前尝试过，但肯定没成功，补发
            self_eid = forward_client.Get().get_self_eid()
            payload = ForwardLogin._make_login_payload(self._login_data_tmp)
            forward_client.Get().send_msg(forward_client.ForwardClient.CMD_LOGIN,
                                          self_eid,
                                          [forward_client.ForwardClient.BROADCAST_EID],
                                          payload)

    @staticmethod
    def _make_login_payload(login_data):
        return struct.pack('i', 0) + pickle.dumps(login_data, forward_client.ForwardClient.PICKLE_VERSION)


# ForwardLogin_Ins = ForwardLogin()
# ForwardLogin_Ins = None


def Get():
    return _g_forward_login_instance


def Set(obj=None):
    global _g_forward_login_instance
    _g_forward_login_instance = obj


